package backend

import (
	"bufio"
	"fmt"
	"io"
	"log"
	"net"
	"os"
	"strconv"
	"strings"
)

// WITSAReceiver WITS-A接收器
type WITSAReceiver struct {
	Host      string
	Port      int
	Listener  net.Listener
	Connected bool
	Buffer    string

	// 字段编码到MSEData属性的映射
	FieldMapping map[string]string

	// 中文字段名映射，用于打印
	ChineseNames map[string]string
}

// NewWITSAReceiver 创建新的WITS-A接收器
func NewWITSAReceiver(host string, port int) *WITSAReceiver {
	return &WITSAReceiver{
		Host: host,
		Port: port,
		FieldMapping: map[string]string{
			"0105": "date",                // 日期
			"0106": "time",                // 时间
			"0108": "depth",               // 井深
			"0118": "TQ_surf",             // 顶驱扭矩
			"0120": "RPM_surf",            // 顶驱转速
			"0121": "vertical_pipe_press", // 立管压力
			"0130": "Q",                   // 入口流量
			"0113": "ROP",                 // 钻时
			"0116": "WOB",                 // 钻压
		},
		ChineseNames: map[string]string{
			"date":                "日期",
			"time":                "时间",
			"depth":               "井深",
			"TQ_surf":             "顶驱扭矩",
			"RPM_surf":            "顶驱转速",
			"vertical_pipe_press": "立管压力",
			"Q":                   "入口流量",
			"ROP":                 "钻时",
			"WOB":                 "钻压",
		},
	}
}

// StartServer 启动WITS-A服务器
func (w *WITSAReceiver) StartServer() error {
	addr := fmt.Sprintf("%s:%d", w.Host, w.Port)
	listener, err := net.Listen("tcp", addr)
	if err != nil {
		return fmt.Errorf("启动服务器失败: %v", err)
	}

	w.Listener = listener
	w.Connected = true
	log.Printf("WITS-A服务器已启动，监听 %s", addr)
	return nil
}

// ParseWITSRecord 解析WITS-A记录并返回MSEData对象
func (w *WITSAReceiver) ParseWITSRecord(recordData string) *MSEData {
	// 创建新的MSEData对象
	mseData := &MSEData{}

	// 分割记录为多行
	lines := strings.Split(strings.TrimSpace(recordData), "\r\n")

	// 检查记录类型（第一条有效数据行）
	recordType := ""
	for _, line := range lines {
		if line != "" && !strings.HasPrefix(line, "&&") && !strings.HasPrefix(line, "!!") {
			// 提取记录类型（前两位）
			if len(line) >= 2 {
				recordType = line[:2]
			}
			break
		}
	}

	// 只处理01类型记录
	if recordType != "01" {
		log.Printf("跳过非01类型记录: %s", recordType)
		return nil
	}

	// 解析字段并填充MSEData对象
	for _, line := range lines {
		if line != "" && !strings.HasPrefix(line, "&&") && !strings.HasPrefix(line, "!!") {
			// 提取字段编码（前4位）
			if len(line) < 4 {
				continue
			}
			fieldCode := line[:4]

			// 检查是否是需要提取的字段
			if fieldName, exists := w.FieldMapping[fieldCode]; exists {
				// 提取字段值（第4位之后的内容）
				fieldValue := line[4:]

				// 根据字段类型设置值
				if fieldName == "date" || fieldName == "time" {
					// 日期和时间保持为字符串
					switch fieldName {
					case "date":
						mseData.Date = &fieldValue
					case "time":
						mseData.Time = &fieldValue
					}
				} else {
					// 其他字段转换为浮点数
					if value, err := strconv.ParseFloat(fieldValue, 64); err == nil {
						switch fieldName {
						case "depth":
							mseData.Depth = &value
						case "TQ_surf":
							mseData.TQSurf = &value
						case "RPM_surf":
							mseData.RPMSurf = &value
						case "vertical_pipe_press":
							mseData.VerticalPipePress = &value
						case "Q":
							mseData.Q = &value
						case "ROP":
							mseData.ROP = &value
						case "WOB":
							mseData.WOB = &value
						}
					} else {
						log.Printf("字段 %s 值转换失败: %s, 错误: %v", fieldName, fieldValue, err)
					}
				}
			}
		}
	}

	return mseData
}

// HandleClient 处理客户端连接
func (w *WITSAReceiver) HandleClient(conn net.Conn) {
	defer conn.Close()
	log.Printf("客户端已连接: %s", conn.RemoteAddr().String())

	reader := bufio.NewReader(conn)
	buffer := make([]byte, 4096)

	for w.Connected {
		n, err := reader.Read(buffer)
		if err != nil {
			log.Printf("读取客户端数据错误: %v", err)
			break
		}

		if n == 0 {
			break
		}

		// 添加到缓冲区
		data := string(buffer[:n])
		w.Buffer += data

		// 处理缓冲区中的完整记录
		for strings.Contains(w.Buffer, "!!") {
			// 查找记录开始和结束位置
			startPos := strings.Index(w.Buffer, "&&")
			endPos := strings.Index(w.Buffer, "!!")

			if startPos == -1 || endPos == -1 || endPos < startPos {
				// 如果没有完整的记录，等待更多数据
				break
			}

			// 提取完整记录
			recordData := w.Buffer[startPos : endPos+2]
			w.Buffer = w.Buffer[endPos+2:]

			// 解析记录
			mseData := w.ParseWITSRecord(recordData)

			// 打印解析结果
			if mseData != nil {
				log.Printf("=== 解析到01类型记录 ===")
				mseData.PrintMSEData(w.ChineseNames)

				mseTransData := TransformObj(*mseData)
				mseTotal, mseDownhole, DOC, DS := CalculateMSE(mseTransData, 8.5, 466, 0.25, 9.5)

				log.Printf("----------计算结果---------------")
				log.Printf("mse_total: %.2f", mseTotal)
				log.Printf("mse_downhole: %.2f", mseDownhole)
				log.Printf("DOC: %.2f", DOC)
				log.Printf("DS: %.2f", DS)
				log.Printf("=================================")
			} else {
				log.Printf("跳过非01类型记录或无效记录")
			}
		}
	}

	log.Printf("客户端连接已关闭: %s", conn.RemoteAddr().String())
}

// Run 运行服务器
func (w *WITSAReceiver) Run() {
	if err := w.StartServer(); err != nil {
		log.Printf("启动服务器失败: %v", err)
		return
	}

	defer w.StopServer()

	for w.Connected {
		log.Printf("等待客户端连接...")
		conn, err := w.Listener.Accept()
		if err != nil {
			if w.Connected {
				log.Printf("接受连接错误: %v", err)
			}
			continue
		}

		log.Printf("接收到来自 %s 的连接", conn.RemoteAddr().String())
		go w.HandleClient(conn)
	}
}

// StopServer 停止服务器
func (w *WITSAReceiver) StopServer() {
	w.Connected = false
	if w.Listener != nil {
		w.Listener.Close()
	}
	log.Printf("WITS-A服务器已停止")
}

// setupLogging 设置日志
func setupLogging() {
	// 创建logs目录
	os.MkdirAll("logs", 0755)

	// 打开日志文件
	file, err := os.OpenFile("logs/wits_a_receiver.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err != nil {
		log.Printf("无法打开日志文件: %v", err)
		return
	}

	// 设置日志输出到文件和控制台
	log.SetOutput(file)

	// 注意：在Go中，log包默认输出到标准错误，我们可以同时输出到文件和控制台
	// 这里我们使用多写入器
	log.SetOutput(io.MultiWriter(os.Stdout, file))

	// 设置日志格式
	log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
}

func main() {
	// 设置日志
	setupLogging()

	// 配置服务器信息
	HOST := "0.0.0.0" // 监听所有接口
	PORT := 5001      // WITS-A服务器端口

	// 创建接收器实例
	receiver := NewWITSAReceiver(HOST, PORT)

	// 运行服务器
	receiver.Run()
}
